using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using ExamPaperEditingSystem.Models;

namespace ExamPaperEditingSystem.Services
{
    public class KnowledgeGraphService : IKnowledgeGraphService
    {
        private readonly IChatService _chatService;
        private readonly List<KnowledgeGraphData> _knowledgeGraphs;
        private readonly string _dataPath;

        public KnowledgeGraphService(IChatService chatService)
        {
            _chatService = chatService;
            _knowledgeGraphs = new List<KnowledgeGraphData>();
            _dataPath = Path.Combine(Environment.CurrentDirectory, "Vector Knowledge Base", "Graphs");
            
            if (!Directory.Exists(_dataPath))
            {
                Directory.CreateDirectory(_dataPath);
            }
        }

        public Task<KnowledgeGraphData> CreateKnowledgeGraphAsync(string name)
        {
            var graph = new KnowledgeGraphData
            {
                Name = name
            };

            _knowledgeGraphs.Add(graph);
            return Task.FromResult(graph);
        }

        public Task<List<KnowledgeGraphData>> GetKnowledgeGraphsAsync()
        {
            return Task.FromResult(_knowledgeGraphs.ToList());
        }

        public Task<KnowledgeGraphData?> GetKnowledgeGraphAsync(string name)
        {
            var graph = _knowledgeGraphs.FirstOrDefault(g => g.Name == name);
            return Task.FromResult(graph);
        }

        public async Task SaveKnowledgeGraphAsync(KnowledgeGraphData graph)
        {
            var filePath = Path.Combine(_dataPath, $"{graph.Name}.json");
            var json = JsonSerializer.Serialize(graph, new JsonSerializerOptions
            {
                WriteIndented = true,
                PropertyNamingPolicy = JsonNamingPolicy.CamelCase
            });
            
            await File.WriteAllTextAsync(filePath, json);
        }

        public async Task DeleteKnowledgeGraphAsync(string name)
        {
            var graph = _knowledgeGraphs.FirstOrDefault(g => g.Name == name);
            if (graph != null)
            {
                _knowledgeGraphs.Remove(graph);
                
                await Task.Run(() =>
                {
                    var filePath = Path.Combine(_dataPath, $"{name}.json");
                    if (File.Exists(filePath))
                    {
                        File.Delete(filePath);
                    }
                });
            }
        }

        public async Task AddNodeAsync(string graphName, KnowledgeNode node)
        {
            var graph = _knowledgeGraphs.FirstOrDefault(g => g.Name == graphName);
            if (graph == null)
            {
                graph = await CreateKnowledgeGraphAsync(graphName);
            }

            graph.Nodes.Add(node);
            graph.UpdatedAt = DateTime.Now;
            await SaveKnowledgeGraphAsync(graph);
        }

        public async Task AddRelationAsync(string graphName, KnowledgeRelation relation)
        {
            var graph = _knowledgeGraphs.FirstOrDefault(g => g.Name == graphName);
            if (graph == null)
            {
                throw new ArgumentException($"知识图谱 {graphName} 不存在");
            }

            graph.Relations.Add(relation);
            graph.UpdatedAt = DateTime.Now;
            await SaveKnowledgeGraphAsync(graph);
        }

        public Task<List<KnowledgeNode>> SearchNodesAsync(string graphName, string query)
        {
            var graph = _knowledgeGraphs.FirstOrDefault(g => g.Name == graphName);
            if (graph == null)
            {
                return Task.FromResult(new List<KnowledgeNode>());
            }

            var results = graph.Nodes.Where(node =>
                node.Label.Contains(query, StringComparison.OrdinalIgnoreCase) ||
                node.Type.Contains(query, StringComparison.OrdinalIgnoreCase) ||
                node.Properties.Values.Any(prop => prop.ToString()?.Contains(query, StringComparison.OrdinalIgnoreCase) == true)
            ).ToList();

            return Task.FromResult(results);
        }

        public Task<List<KnowledgeRelation>> GetRelationsAsync(string graphName, string nodeId)
        {
            var graph = _knowledgeGraphs.FirstOrDefault(g => g.Name == graphName);
            if (graph == null)
            {
                return Task.FromResult(new List<KnowledgeRelation>());
            }

            var relations = graph.Relations.Where(r => r.SourceId == nodeId || r.TargetId == nodeId).ToList();
            return Task.FromResult(relations);
        }

        public async Task LoadKnowledgeGraphsAsync()
        {
            _knowledgeGraphs.Clear();
            
            if (!Directory.Exists(_dataPath))
            {
                return;
            }

            var files = Directory.GetFiles(_dataPath, "*.json");
            foreach (var file in files)
            {
                try
                {
                    var json = await File.ReadAllTextAsync(file);
                    var graph = JsonSerializer.Deserialize<KnowledgeGraphData>(json, new JsonSerializerOptions
                    {
                        PropertyNamingPolicy = JsonNamingPolicy.CamelCase
                    });
                    
                    if (graph != null)
                    {
                        _knowledgeGraphs.Add(graph);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"加载知识图谱文件 {file} 失败: {ex.Message}");
                }
            }
        }

        public async Task ExtractKnowledgeFromTextAsync(string graphName, string text)
        {
            try
            {
                var prompt = $@"请从以下文本中提取知识实体和关系，并以JSON格式返回：

文本：{text}

请返回格式如下：
{{
  ""nodes"": [
    {{
      ""label"": ""实体名称"",
      ""type"": ""实体类型"",
      ""properties"": {{
        ""description"": ""实体描述""
      }}
    }}
  ],
  ""relations"": [
    {{
      ""source"": ""源实体名称"",
      ""target"": ""目标实体名称"",
      ""type"": ""关系类型""
    }}
  ]
}}";

                var response = await _chatService.SendMessageAsync(prompt, new List<ChatMessage>());
                var jsonContent = ExtractJsonFromResponse(response.Content);
                
                if (!string.IsNullOrEmpty(jsonContent))
                {
                    var extractedData = JsonSerializer.Deserialize<JsonElement>(jsonContent);
                    
                    // 添加节点
                    if (extractedData.TryGetProperty("nodes", out var nodesElement))
                    {
                        foreach (var nodeElement in nodesElement.EnumerateArray())
                        {
                            var node = new KnowledgeNode
                            {
                                Label = nodeElement.GetProperty("label").GetString() ?? "",
                                Type = nodeElement.GetProperty("type").GetString() ?? ""
                            };
                            
                            if (nodeElement.TryGetProperty("properties", out var propsElement))
                            {
                                foreach (var prop in propsElement.EnumerateObject())
                                {
                                    node.Properties[prop.Name] = prop.Value.GetString() ?? "";
                                }
                            }
                            
                            await AddNodeAsync(graphName, node);
                        }
                    }
                    
                    // 添加关系
                    if (extractedData.TryGetProperty("relations", out var relationsElement))
                    {
                        var graph = _knowledgeGraphs.FirstOrDefault(g => g.Name == graphName);
                        if (graph != null)
                        {
                            foreach (var relationElement in relationsElement.EnumerateArray())
                            {
                                var sourceLabel = relationElement.GetProperty("source").GetString() ?? "";
                                var targetLabel = relationElement.GetProperty("target").GetString() ?? "";
                                
                                var sourceNode = graph.Nodes.FirstOrDefault(n => n.Label == sourceLabel);
                                var targetNode = graph.Nodes.FirstOrDefault(n => n.Label == targetLabel);
                                
                                if (sourceNode != null && targetNode != null)
                                {
                                    var relation = new KnowledgeRelation
                                    {
                                        SourceId = sourceNode.Id,
                                        TargetId = targetNode.Id,
                                        Type = relationElement.GetProperty("type").GetString() ?? ""
                                    };
                                    
                                    await AddRelationAsync(graphName, relation);
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"从文本提取知识失败: {ex.Message}");
            }
        }

        private static string ExtractJsonFromResponse(string response)
        {
            // 尝试提取JSON内容
            var jsonStart = response.IndexOf('{');
            var jsonEnd = response.LastIndexOf('}');
            
            if (jsonStart >= 0 && jsonEnd > jsonStart)
            {
                return response.Substring(jsonStart, jsonEnd - jsonStart + 1);
            }
            
            return string.Empty;
        }
    }
}